package org.geppeto.eva.synchronizer;

import java.util.ArrayList;
import java.util.Iterator;

public class Mailbox {
	private int _counterMsg;
	private int _counterReaders;
	private InstanceManager _inst;
	private ArrayList<String> listOfMsg = new ArrayList<String>();
	private ArrayList<String> listOfReaders = new ArrayList<String>();
	
	public Mailbox(InstanceManager inst){
		_counterMsg = 0;
		_counterReaders = 0;
		_inst = inst;
	}

	protected String getMessage(String userID){
		try{
			String result="";
			if (_counterMsg >0) {
				String msgText = listOfMsg.get(0);
				listOfMsg.remove(0);
				_counterMsg--;
				//publish _counter --> ALL
				
				//TODO deliver msgText --> the ONE who invoked getMessage
				//If reader is TokenSalter, getMessage was invoked directly
				//so result will return to token function by
				
				result = "{\"description\": \"got_message\", " +
				"\"modification\": {\"msgCnt\": \"" +
				Integer.toString(_counterMsg) + "\", " +
				"\"msgText\": \"" + msgText +
				"\"}}";
				return result;
			} else {
				listOfReaders.add(userID); //add reader
				_counterReaders++;
				//Publish new user in the list --> ALL
				result = "{\"description\": \"reader_added\", " +
				"\"modification\": {\"added\": \"" + userID + "\", "
				+ "\"listOfReaders\": \"" + stringifyArrayList2JSON(listOfReaders)
				+ "\"}}";
				return result;
			}
		}catch (Exception ex){
			return "Failed";
		}

	}	

	protected String putMessage(String userID, String msg){
		try{
			String result;
			if (_counterMsg == 0 && !(listOfReaders.isEmpty()) ) {
				String user = listOfReaders.get(0);
				listOfReaders.remove(0);
				_counterReaders--;
				//If reader is Token, notify THIS reader, 
				if (user.startsWith(InstanceManager.TOKEN_CALLBACK)){
					String tokenInst = user.substring(InstanceManager.TOKEN_CALLBACK.length());
					_inst.callbackToken(tokenInst, msg);
				}

				//Is it important to know what msgText was received? 
				//Well YES, TODO the reader has to get that message somehow
				//Like token gets it in "if" above
				//This message delivery can be implemented in InstanceManager
				result = "{\"description\": \"message_delivered\", " +
				"\"modification\": {\"removed\": \"" + userID + "\", "
				+ "\"listOfReaders\": \"" + stringifyArrayList2JSON(listOfReaders)
				+ "\"}}";  
				return result;
			} else {
				listOfMsg.add(msg);
				_counterMsg++;
				//Publish new counter --> ALL
				//It is important to know what msgText was received TODO
				result = "{\"description\": \"message_queued\", " +
				"\"modification\": {\"msgCnt\": \"" +
				Integer.toString(_counterMsg) + "\", " +
				"\"msgText\": \"" + msg +
				"\"}}";					
				return result;
			}
		}catch (Exception ex){
			return "Failed";
		}
	}	

	protected String getInfo(){
		String result = "";
		String li = "";
		int counter=0;
		result += "{mechanism: {\"type\": \"Mailbox\", ";
		if (_counterMsg > 0) {
			li = stringifyArrayList2JSON(listOfMsg);
			counter = _counterMsg;
			result += "\"msgCnt\": \"";
		}
		else if (_counterReaders > 0) {
			li = stringifyArrayList2JSON(listOfReaders);
			counter = _counterReaders;
			result += "\"readerCnt\": \"";
		}
		result += Integer.toString(counter) + "\", " +
				"\"list\": " + li + "\"}}";		
		return result;
	}
	
	private String stringifyArrayList2JSON(ArrayList<String> li){
		//http://www.sigpwned.com/projects/jsonification
		String result="[";
		int i=0;
		Iterator<String> itr = li.iterator();
	    while (itr.hasNext()){	    	
	    	if (i != 0) result+=", ";
	    	result += "\"" + itr.next() + "\"";
	    	i++;
	    }
	    result+="]";
	    return result;
	}
}
